package com.xing.oauth.server.service.impl;

import com.xing.oauth.server.config.AligenieProperties;
import com.xing.oauth.server.model.OauthDto;
import com.xing.oauth.server.model.TokenDto;
import com.xing.oauth.server.model.mapper.AligenieTokenMapper;
import com.xing.oauth.server.service.AligenieTokenService;
import com.xing.oauth.util.DateValidUtil;
import org.apache.ibatis.annotations.Select;
import org.apache.oltu.oauth2.as.issuer.MD5Generator;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuer;
import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl;
import org.apache.oltu.oauth2.as.request.OAuthTokenRequest;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.Date;


@Service
public class AligenieTokenServiceImpl implements AligenieTokenService {
    protected static final Logger LOGGER = LoggerFactory.getLogger(AligenieTokenServiceImpl.class);

    @Autowired
    private AligenieTokenMapper aligenieTokenMapper;

    @Autowired
    private AligenieProperties configure;

    /**
     * 刷新token
     *
     * @param oAuthTokenRequest
     * @return
     */
    public TokenDto refreshToken(OAuthTokenRequest oAuthTokenRequest) throws ParseException, OAuthSystemException {
        TokenDto token = aligenieTokenMapper.getTokenByRefreshToken(oAuthTokenRequest.getRefreshToken());
        //判断token信息是否存在
        if (token == null) {
            LOGGER.info("token不存在: {}", token);
            return null;
        }
        //判断长短token费否有效
        boolean vallid = DateValidUtil.isVallid(token.getCreatedDt(), configure.getRtExpiresIn());
        //正常的情况，没有失效
        if (!vallid) {
            //token失效后，手动删除数据库里面的token的记录
            LOGGER.info("refresh_token超时，AtExpiresIn:{}", configure.getRtExpiresIn());
            aligenieTokenMapper.deleteToken(token.getId());
            return null;
        }

        //生成Access Token
        OAuthIssuer oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
        final String accessToken = oauthIssuerImpl.accessToken();

        TokenDto refresh = new TokenDto();
        refresh.setAccessToken(accessToken);
        refresh.setUpdatedDt(new Date());
        refresh.setId(token.getId());

        //这个是重新生成个新的token，放里面，直接把数据库里面的值更新掉
        aligenieTokenMapper.updateToken(refresh);
        refresh.setAtExpiresIn(configure.getAligenieAtExpiresIn());
        refresh.setRefreshToken(oAuthTokenRequest.getRefreshToken());
        LOGGER.info("刷新token返回accessToken:{},refreshToken:{},atEcpires:{}", accessToken, oAuthTokenRequest.getRefreshToken(), configure.getAligenieAtExpiresIn());
        return refresh;
    }

    /**
     * 通过code生成token
     *
     * @param oAuthRequest
     * @return
     */
    public TokenDto accessToken(OAuthTokenRequest oAuthRequest) throws ParseException, OAuthSystemException {
        //获取阿里code信息
        OauthDto codes = aligenieTokenMapper.getOauthByCode(oAuthRequest.getCode());
        //判断code信息是否存在
        if (codes == null) {
            LOGGER.info("code不存在：{}", codes);
            return null;
        }

        //删除code信息
        aligenieTokenMapper.deleteOauthCode(oAuthRequest.getCode());
        //检验code码，是否有效
        boolean vallid = DateValidUtil.isVallid(codes.getCreateDt(), configure.getCodeExpiresIn());
        if (!vallid) {
            LOGGER.info("access_token超时，codeExpiresIn:{}", configure.getCodeExpiresIn());
            return null;
        }

        //生成Access Token
        OAuthIssuerImpl oAuthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
        //final修饰，意味着这个accessToken不能改变
        final String accessToken = oAuthIssuerImpl.accessToken();
        final String refreshToken = oAuthIssuerImpl.refreshToken();

        TokenDto token = new TokenDto();
        token.setAccessToken(accessToken);
        token.setRefreshToken(refreshToken);
        token.setNlcId(codes.getNlcId());
        token.setCreatedDt(new Date());
        token.setUpdatedDt(new Date());
        token.setRtExpiresIn(configure.getRtExpiresIn());
        token.setAtExpiresIn(configure.getAligenieAtExpiresIn());
        token.setAligenieToken(codes.getAligenieToken());

        //查询aligenieToken是否存在，一个天猫账户只有一个aligenieToken
        TokenDto tokenDto = aligenieTokenMapper.getTokenByAligenieToken(codes.getAligenieToken());
        if (tokenDto != null) {
            //token已经存在则更新
            aligenieTokenMapper.updateTokenInfo(token);
        } else {
            //否则保存最新的token
            aligenieTokenMapper.saveToken(token);
        }
        LOGGER.info("长短token返回accessToken：{}，refreshToken:{},atExpries:{}",
                accessToken, refreshToken, configure.getAligenieAtExpiresIn());
        return token;
    }


    /**
     * 通过阿里的token获取token信息
     *
     * @param token
     * @return
     */
    public TokenDto getTokenByAligenieToken(String token) {
        return aligenieTokenMapper.getTokenByAligenieToken(token);
    }

    /**
     * 删除token
     * @param id
     */
    public void deleteToken(Integer id) {
        aligenieTokenMapper.deleteToken(id);
    }
}





























